package com.kingcat.smartchair.utils;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import androidx.core.content.FileProvider;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kingcat.smartchair.MainActivity;
import com.kingcat.smartchair.R;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;

public     /**
 * 更新应用
 *
 * @author Administrator
 */
class AutoUpdateTask {

    private Activity mActivity;

    private Context mContext;

    private static String apkName = "smartchairupdate.apk";

    private static String packageName = "com.kingcat.smartchairupdate";

    public AutoUpdateTask(Activity activity, Context context) {
        this.mActivity = activity;
        this.mContext = context;
    }

    // 检测是否需要更新
    public void CheckUpdate(){

        Log.d("*********************************************", "update begin!");

        // 检测版本号
        String checkUrl = "";
        if(AppUtils.getAppContext().getString(R.string.app_env).equals("prod"))
        {
            checkUrl = AppUtils.getAppContext().getString(R.string.smartchari_apkupdateinfourl_prod);
        }

        if(AppUtils.getAppContext().getString(R.string.app_env).equals("dev"))
        {
            checkUrl = AppUtils.getAppContext().getString(R.string.smartchari_apkupdateinfourl_dev);
        }

        String res = Tools.doGET(checkUrl);
        JSONObject jsonObject = JSON.parseObject(res);

        // 安装升级程序
        String url = jsonObject.getString("UpdateDownloadUrl");
        download(url);
    }

    private String download(String Url) {

        Log.d("*********************************************",  " 准备下载：" + Url );

        InputStream input = null;
        OutputStream output = null;
        HttpURLConnection connection = null;
        File file = null;
        try {
            URL url = new URL(Url);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            // expect HTTP 200 OK, so we don't mistakenly save error
            // report
            // instead of the file
            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                return "Server returned HTTP "
                        + connection.getResponseCode() + " "
                        + connection.getResponseMessage();
            }
            // this will be useful to display download percentage
            // might be -1: server did not report the length
            int fileLength = connection.getContentLength();

            Log.d("*********************************************",  " 文件大小：" + String.valueOf(fileLength) );

            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {

                String apkPath = mContext.getExternalCacheDir().getPath()+ File.separator + "app" + File.separator;
                file = new File(apkPath, apkName);

                if (!file.exists()) {
                    // 判断父文件夹是否存在
                    if (!file.getParentFile().exists()) {
                        file.getParentFile().mkdirs();
                    }
                }
                else
                {
                    file.delete();
                    file = new File(apkPath, apkName);
                }
            } else {
                Toast.makeText(mActivity, "sd卡未挂载",
                        Toast.LENGTH_LONG).show();
            }

            // 讲下载的文件流写到本地
            input = connection.getInputStream();
            output = new FileOutputStream(file);
            byte data[] = new byte[4096];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                total += count;
                output.write(data, 0, count);

                Log.d("*********************************************",  " 已下载：" + String.valueOf(total) );
            }

            //调用，apkPath 入参就是 xml 中共享的路径
            String apkPath = mContext.getExternalCacheDir().getPath()+ File.separator + "app" + File.separator;
            clientInstall(apkPath + apkName);
        } catch (Exception e) {
            //System.out.println("err:" + e.toString());
            Log.d("*********************************************",  " 下载异常：" + e.toString());
            return e.toString();

        } finally {
            try {
                if (output != null)
                    output.close();
                if (input != null)
                    input.close();
            } catch (IOException ignored) {
            }
            if (connection != null)
                connection.disconnect();
        }
        return null;
    }

    //需要传下载后的apk的绝对路径和当前上下文，这个方法的返回值表示为：安装成功是true，安装失败是false
    //apkPath:apk文件的绝对路径
    private boolean clientInstall(String apkPath) {
        boolean result = false;
        DataOutputStream dataOutputStream = null;
        BufferedReader errorStream = null;
        BufferedReader successStream = null;
        Process process = null;
        try {
            // 申请 su 权限
            process = Runtime.getRuntime().exec("su");
            dataOutputStream = new DataOutputStream(process.getOutputStream());
            // 执行 pm install 命令  （这是apk安装命令）
            String command = "pm install -r " + apkPath + "\n";
            //执行  am start -n   命令   （这是apk重启命令）    -----.MainActivity是默认重启app后要打开哪个界面
            //String runApp = "am start -n  "+context.getPackageName()+"/"+context.getPackageName()+".MainActivity >>/dev/null 2>&1;";
            //这样子写也是可以的，用\n结尾也可以
            //String runApp = "am start -n  " + packageName + "\n";
            //command= command + runApp;
            Log.d("","走到这里，---------------打印静默安装命令="+command);

            dataOutputStream.write(command.getBytes(Charset.forName("UTF-8")));
            dataOutputStream.writeBytes("exit\n");
            Log.d("","走到这里，---------------打印静默安装完成");

            dataOutputStream.flush();
            process.waitFor();
            errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            StringBuilder errorMsg = new StringBuilder();
            String line;
            while ((line = errorStream.readLine()) != null) {
                errorMsg.append(line);
            }
            Log.d("","走到这里，---------------silent install error message:{}="+errorMsg);

            StringBuilder successMsg = new StringBuilder();
            successStream = new BufferedReader(new InputStreamReader(process.getInputStream()));
            // 读取命令执行结果
            while ((line = successStream.readLine()) != null) {
                successMsg.append(line);
            }
            Log.d("","走到这里，---------------silent install success message:{}="+successMsg);

            // 如果执行结果中包含 Failure 字样就认为是操作失败，否则就认为安装成功
            if (!(errorMsg.toString().contains("Failure") || successMsg.toString().contains("Failure"))) {
                result = true;
            }

            // 重启机器
            DeviceUt.rootCall("reboot");
        } catch (Exception e) {
            Log.d("","走到这里，---------------e="+e);
        } finally {
            try {
                if (process != null) {
                    process.destroy();
                }
                if (dataOutputStream != null) {
                    dataOutputStream.close();
                }
                if (errorStream != null) {
                    errorStream.close();
                }
                if (successStream != null) {
                    successStream.close();
                }
            } catch (Exception e) {
                // ignored
            }
        }
        return result;
    }
}
